package com.diamondsys.embrapa;

import com.diamondsys.embrapa.util.JsfUtil;
import com.diamondsys.embrapa.util.JsfUtil.PersistAction;

import com.lowagie.text.BadElementException;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import java.io.File;
import java.io.IOException;

import java.io.Serializable;
import java.util.Date;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;


@Named("visitasController")
@SessionScoped
public class VisitasController implements Serializable {

    @EJB 
    private com.diamondsys.embrapa.VisitasFacade ejbFacade;
    private List<Visitas> items = null;
    private Visitas selected;
    private Visitas selectedEncerrar;
    private TbInst selectedCliente;
    
    public VisitasController() {
    }

    //Filtro Data Entrada
    private Date dateFrom;
    private Date dateTo;

    public Date getDateFrom() {
        return dateFrom;
    }

    public void setDateFrom(Date dateFrom) {
        this.dateFrom = dateFrom;
    }

    public Date getDateTo() {
        return dateTo;
    }

    public void setDateTo(Date dateTo) {
        this.dateTo = dateTo;
    }
    
    public boolean filterByDate(Object value, Object filter, Locale locale) {
        boolean ret=true;
        
        String filterText = (value == null) ? null : value.toString().trim();
        if (filterText == null || filterText.isEmpty()) {
            return true;
        }
        
        DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
        Date filterDate;

        try {
            filterDate = df.parse(filterText);
            if (dateFrom != null && dateFrom.after(filterDate)) ret = false;
            if (dateTo != null && dateTo.before(filterDate)) ret = false;

        } catch (ParseException e) {
            return true;
        }

       return ret;
    } 

    //Filtro Data Saída
    private Date dateFromSaida;
    private Date dateToSaida;

    public Date getDateFromSaida() {
        return dateFromSaida;
    }

    public void setDateFromSaida(Date dateFromSaida) {
        this.dateFromSaida = dateFromSaida;
    }

    public Date getDateToSaida() {
        return dateToSaida;
    }

    public void setDateToSaida(Date dateToSaida) {
        this.dateToSaida = dateToSaida;
    }
    
    public boolean filterByDateSaida(Object value, Object filter, Locale locale) {
        boolean ret=true;
        
        String filterText = (value == null) ? null : value.toString().trim();
        if (filterText == null || filterText.isEmpty()) {
            return true;
        }
        
        DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
        Date filterDate;

        try {
            filterDate = df.parse(filterText);
            if (dateFromSaida != null && dateFromSaida.after(filterDate)) ret = false;
            if (dateToSaida != null && dateToSaida.before(filterDate)) ret = false;

        } catch (ParseException e) {
            return true;
        }

       return ret;
    } 
    
    public void preProcessorPDF(Object document){
        Document pdf = (Document) document;
        pdf.setPageSize(PageSize.A10);
     }

    public Visitas getSelected() {
        return selected;
    }

    public void setSelected(Visitas selected) {
        this.selected = selected;
    }

    protected void setEmbeddableKeys() {
    }

    protected void initializeEmbeddableKey() {
    }

    private VisitasFacade getFacade() {
        return ejbFacade;
    }

    public Visitas prepareCreate() {
        selected = new Visitas();
        selected.setDataEntrada(new Date());
        selected.setHoraEntrada(new Date());
        selectedEncerrar = null;
        initializeEmbeddableKey();
        if (selectedCliente!= null) selected.setTbInstCodInstituicao(selectedCliente);
        return selected;
    }

    public void create() {
        persist(PersistAction.CREATE, ResourceBundle.getBundle("/Bundle").getString("VisitasCreated"));
        if (!JsfUtil.isValidationFailed()) {
            items = null;    // Invalidate list of items to trigger re-query.
        }
    }

    public void encerrar() {
        if (this.selectedEncerrar != null) selected =selectedEncerrar;
        persist(PersistAction.UPDATE, "Visita encerrada com sucesso!");
        if (!JsfUtil.isValidationFailed()) {
            items = null;    // Invalidate list of items to trigger re-query.
        }
    }
    
    public void update() {
        persist(PersistAction.UPDATE, ResourceBundle.getBundle("/Bundle").getString("VisitasUpdated"));
    }

    public void destroy() {
        persist(PersistAction.DELETE, ResourceBundle.getBundle("/Bundle").getString("VisitasDeleted"));
        if (!JsfUtil.isValidationFailed()) {
            selected = null; // Remove selection
            items = null;    // Invalidate list of items to trigger re-query.
        }
    }

    public List<Visitas> getItems() {

        if (selectedCliente != null) items = getFacade().findByClienteId(selectedCliente);
        else items = getFacade().findAll();

        return items;
    }
    
    public List<Visitas> findAbertasByClienteId(TbInst clienteId) {
        return getFacade().findAbertasByClienteId(clienteId);
    }

    public String customFormatDate(Date date) {
        return JsfUtil.customFormatDate(date);
    }
    
    public String customFormatHour(Date date) {
        return JsfUtil.customFormatHour(date);
    }
    public String getFuncionarioNameByCodigo(String codFunc)
    {
        RhTbFuncionarioController rhTbFuncionarioController = (RhTbFuncionarioController) FacesContext.getCurrentInstance().getApplication().getELResolver().
                        getValue(FacesContext.getCurrentInstance().getELContext(), null, "rhTbFuncionarioController");
        
        RhTbFuncionario funcionario =  rhTbFuncionarioController.getRhTbFuncionario(codFunc);
                
        return (funcionario != null)? funcionario.getNomeFunc() : "";
                    
    }
    
    private void persist(PersistAction persistAction, String successMessage) {
        if (selected != null) {
            setEmbeddableKeys();
            try {
                if (persistAction != PersistAction.DELETE) {
                    
                    if (persistAction == persistAction.CREATE)
                    {
                        if(selected.getDataEntrada() == null || selected.getDataEntrada().after(new Date()))
                        {
                            selected.setDataAtendimento(new Date());
                            selected.setDataEntrada(new Date());
                            selected.setHoraEntrada(new Date());
                        }else{
                            selected.setDataAtendimento(selected.getDataEntrada());
                            selected.setDataEntrada(selected.getDataEntrada());
                            selected.setHoraEntrada(selected.getHoraEntrada());
                        }
                    }
                    else
                    {
                        if (    selected.getDataSaida() == null
                             || selected.getHoraSaida() == null
                             || selected.getDataSaida().before(selected.getDataEntrada())
                             || (selected.getDataSaida().equals(selected.getDataEntrada()) && selected.getHoraSaida().before(selected.getHoraEntrada()))){
                            JsfUtil.addWarningMessage("A data de saída deve ser posterior a data de entrada!");
                            JsfUtil.setValidationFailed();
                            return;
                        }                        
                    }
                    
                    selected.setTbInstCodInstituicao(selectedCliente);
                    getFacade().edit(selected);
                    
                    TbInstController clienteController = (TbInstController) FacesContext.getCurrentInstance().getApplication().getELResolver().
                        getValue(FacesContext.getCurrentInstance().getELContext(), null, "tbInstController");
                    
                    clienteController.ClearItems();
                    
                    
                } else {
                    getFacade().remove(selected);
                }
                JsfUtil.addSuccessMessage(successMessage);
            } catch (EJBException ex) {
                String msg = "";
                Throwable cause = ex.getCause();
                if (cause != null) {
                    msg = cause.getLocalizedMessage();
                }
                if (msg.length() > 0) {
                    JsfUtil.addErrorMessage(msg);
                } else {
                    JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
                }
            } catch (Exception ex) {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
                JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            }
        }
    }

    public Visitas getVisitas(java.lang.Integer id) {
        return getFacade().find(id);
    }

    public List<Visitas> getItemsAvailableSelectMany() {
        return getFacade().findAll();
    }

    public List<Visitas> getItemsAvailableSelectOne() {
        return getFacade().findAll();
    }

    /**
     * @return the selectedCliente
     */
    public TbInst getSelectedCliente() {
        return selectedCliente;
    }

    /**
     * @param selectedCliente the selectedCliente to set
     */
    public void setSelectedCliente(TbInst selectedCliente) {
        this.selectedCliente = selectedCliente;
    }

    /**
     * @return the selectedEncerrar
     */
    public Visitas getSelectedEncerrar() {
        return selectedEncerrar;
    }

    /**
     * @param selectedEncerrar the selectedEncerrar to set
     */
    public void setSelectedEncerrar(Visitas selectedEncerrar) {
        
        if(selectedEncerrar != null && (selectedEncerrar.getDataSaida() == null || selectedEncerrar.getDataSaida().before(new Date())))
        {
            selectedEncerrar.setDataSaida(new Date());
            selectedEncerrar.setHoraSaida(new Date());
        }
        
        this.selectedEncerrar = selectedEncerrar;
    }

    @FacesConverter(forClass=Visitas.class)
    public static class VisitasControllerConverter implements Converter {

        @Override
        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            VisitasController controller = (VisitasController)facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "visitasController");
            return controller.getVisitas(getKey(value));
        }

        java.lang.Integer getKey(String value) {
            java.lang.Integer key;
            key = Integer.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Integer value) {
            StringBuilder sb = new StringBuilder();
            sb.append(value);
            return sb.toString();
        }

        @Override
        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Visitas) {
                Visitas o = (Visitas) object;
                return getStringKey(o.getId());
            } else {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "object {0} is of type {1}; expected type: {2}", new Object[]{object, object.getClass().getName(), Visitas.class.getName()});
                return null;
            }
        }

    }

}
